package com.aca.market.controller;


import com.aca.market.entity.Catalog;
import com.aca.market.entity.Item;
import com.aca.market.entity.Storage;
import com.aca.market.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;


/**
 * <p>
 * 商品表 前端控制器
 * </p>
 *
 * @author aca
 * @since 2020-11-13
 */
@Controller
@Slf4j
public class ItemController {

    @Autowired
    IItemService itemService;
    @Autowired
    ICatalogService catalogService;
    @Autowired
    IStorageService storageService;
    @Autowired
    IIndentService indentService;
    @Autowired
    ICartService cartService;

    //前台

    @GetMapping("/shop/items")
    public String getDefaultItemPage(){
        return "redirect:/shop/items/page/1";
    }

    //普通分页
    @GetMapping("/shop/items/page/{pageNum}")
    public String getPageItems(@PathVariable Integer pageNum, Model model){

        //初始化分类
//        Map<String, List<String>> allCatalogMap = catalogService.getAllCatalogMap();
        Map<Catalog, List<Catalog>> catalogMap = catalogService.getCatalogMap();

        Page<Item> page = new Page<>(pageNum,9);
        //升序 每页九个商品
        IPage<Item> itemPage = itemService.selectItemPage(page, new QueryWrapper<Item>().orderByAsc("id"));
        List<Item> items = itemPage.getRecords();
        //处理多图片链接情况 多线程下图片延迟无所谓 不加锁了
        for (Item item : items) {
            int flag = item.getImage().indexOf(",");
            if (flag > 0){
                item.setImage(item.getImage().substring(0,flag));
            }
        }
        BigDecimal[] priceLimit = itemService.getLimitPrice();
        model.addAttribute("priceMin",priceLimit[0].toBigInteger());
        model.addAttribute("priceMax",priceLimit[1].toBigInteger());
        model.addAttribute("items",items);
        model.addAttribute("page",page);
        model.addAttribute("catalog",catalogMap);
        return "shop";
    }

    @GetMapping("/shop/items/search/{pageNum}")
    public String researchItems(@PathVariable Integer pageNum,
                                @RequestParam String name,
                                Model model){

        Page<Item> page = new Page<>(pageNum,9);
        itemService.selectItemPage(page,new QueryWrapper<Item>().like("name", name));
        BigDecimal[] priceLimit = itemService.getLimitPrice();
        model.addAttribute("priceMin",priceLimit[0].toBigInteger());
        model.addAttribute("priceMax",priceLimit[1].toBigInteger());
//        model.addAttribute("items",items);
//        model.addAttribute("page",page);
//        model.addAttribute("catalog",catalogMap);
//        model.addAttribute("typeId",typeId);
        return "";
    }

    //按照选的分类分页
    @GetMapping("/shop/items/catalog/{pageNum}")
    public String getCatalogItems(@PathVariable Integer pageNum,
                                  @RequestParam Long typeId,Model model){
        Page<Item> page = new Page<>(pageNum,9);
        IPage<Item> itemPage = itemService.selectItemPage(page,
                new QueryWrapper<Item>().eq("type", typeId).orderByAsc("id"));


        //初始化分类
//        Map<String, List<String>> allCatalogMap = catalogService.getAllCatalogMap();
        Map<Catalog, List<Catalog>> catalogMap = catalogService.getCatalogMap();
        List<Item> items = itemPage.getRecords();
        //处理多图片链接情况 多线程下图片延迟无所谓 不加锁了
        for (Item item : items) {
            int flag = item.getImage().indexOf(",");
            if (flag > 0){
                item.setImage(item.getImage().substring(0,flag));
            }
        }
        BigDecimal[] priceLimit = itemService.getLimitPrice();
        model.addAttribute("priceMin",priceLimit[0].toBigInteger());
        model.addAttribute("priceMax",priceLimit[1].toBigInteger());
        model.addAttribute("items",items);
        model.addAttribute("page",page);
        model.addAttribute("catalog",catalogMap);
        model.addAttribute("typeId",typeId);
        return "shop";
    }

    @GetMapping("/shop/items/price/{pageNum}")
    public String listByPrice(@RequestParam BigDecimal min,
                              @RequestParam BigDecimal max,
                              @RequestParam(required = false) Long typeId,
                              @PathVariable Long pageNum, Model model){

        Page<Item> page = new Page<>(pageNum,9);
        IPage<Item> itemPage;
        if (typeId == null){
             itemPage = itemService.selectItemPage(page, new QueryWrapper<Item>()
                    .between("price_sell",min,max)
                    .orderByAsc("price_sell"));
        }else {
            itemPage = itemService.selectItemPage(page, new QueryWrapper<Item>()
                    .eq("type", typeId)
                    .between("price_sell",min,max)
                    .orderByAsc("price_sell"));
        }
        Map<Catalog, List<Catalog>> catalogMap = catalogService.getCatalogMap();
        List<Item> items = itemPage.getRecords();
        //处理多图片链接情况 多线程下图片延迟无所谓 不加锁了
        for (Item item : items) {
            int flag = item.getImage().indexOf(",");
            if (flag > 0){
                item.setImage(item.getImage().substring(0,flag));
            }
        }
        BigDecimal[] priceLimit = itemService.getLimitPrice();
        model.addAttribute("priceMin",priceLimit[0].toBigInteger());
        model.addAttribute("priceMax",priceLimit[1].toBigInteger());
        model.addAttribute("items",items);
        model.addAttribute("page",page);
        model.addAttribute("catalog",catalogMap);
        model.addAttribute("typeId",typeId);
        return "shop";
    }

    @GetMapping("/shop/detail/{itemId}")
    public String toItemDetail(@PathVariable("itemId")Long itemId, Model model){
        Item item = itemService.getById(itemId);
        List<String> detailImages = itemService.getDetailImages(itemId);
        Storage stock = storageService.getById(itemId);
        //商品推荐
        List<Item> ItemList = itemService.getItemListByType(item.getType());
        model.addAttribute("typeItem",ItemList);
        model.addAttribute("stock",stock);
        model.addAttribute("images",detailImages);
        model.addAttribute("pic",detailImages.get(0));
        model.addAttribute("item",item);
        return "product-single";
    }

    //加入购物车，但不做跳转，与下一个方法有区别
    @GetMapping("/shop/cart/increment")
    public String addToCartBg(@RequestParam("itemId") Long itemId){

        Item item = itemService.getById(itemId);
        cartService.addToCart(item);
        return "redirect:/dashboard/pick";
    }


    @GetMapping("/shop/addToCart/{itemId}")
    public String addToCart(@PathVariable("itemId")Long itemId){
        Item item = itemService.getById(itemId);
        if (cartService.addToCart(item) != "no-auth"){
            //->cartController
            return "redirect:/cart/";
        }
        return "/login";
    }

    @PostMapping("/shop/cart/add/{itemId}")
    @ResponseBody
    public Item cartAddQty(@PathVariable("itemId") Long itemId){
        Item item = itemService.getById(itemId);
        System.out.println("==================ADD"+item.toString());
        Future<Boolean> future = cartService.addItemQty(item);
        try {
            if (future.get(5, TimeUnit.SECONDS)){ return item; }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }

        //空item即失败
        return new Item();
    }

    @PostMapping("/shop/cart/cut/{itemId}")
    @ResponseBody
    public Item cartNumCut(@PathVariable("itemId") Long itemId){
        Item item = itemService.getById(itemId);
        log.info("==================CUT"+item.toString());
        Future<Boolean> future = cartService.cutItemQty(item);
        try {
            if (future.get(2, TimeUnit.SECONDS)){ return item; }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
        return new Item();
    }

    @PostMapping("/shop/cart/del/{itemId}")
    @ResponseBody
    public Item cartNumClear(@PathVariable("itemId") Long itemId){
        Item item = itemService.getById(itemId);
        log.info("==================CLEAR"+item.toString());
        Future<Boolean> future = cartService.delItem(item);
        try {
            if (future.get(5, TimeUnit.SECONDS)){ return item; }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
        return new Item();
    }


    //后台

    @GetMapping("/item/detail")
    public String getItem(@RequestParam Long itemId,Model model){
        Item item = itemService.getById(itemId);
//        Storage storage = storageService.getById(itemId);
        model.addAttribute("itemDetail",item);
//        model.addAttribute("storage",storage);
        return "item-detail";
    }


    @GetMapping("/item/list")
    public String listItem(@RequestParam(defaultValue = "1") Integer pageNum,
                           @RequestParam(required = false) LocalDateTime start,
                           @RequestParam(required = false) LocalDateTime end,
                           @RequestParam(required = false) String name,
                           @RequestParam(required = false,name = "typeIdList[]") List<Long> typeIdList,
                           Model model){
        Page<Item> page = new Page(pageNum,16);
        List<Item> items = itemService.selectItemPage(page,new QueryWrapper<Item>()
                .orderByAsc("id")
                .in(typeIdList!=null&&!typeIdList.isEmpty(),"type",typeIdList)
                .between(start!=null&&end!=null,"updated_time",start,end)
                .like(name!=null&&!name.trim().isEmpty(),"name",name))
                .getRecords();
        Map<Long, Storage> storageMap = storageService.getIdStorageMap(items);
        Map<Long,String> types = catalogService.getAllIdNameMap();
        model.addAttribute("types",types);
        model.addAttribute("page",page);
        model.addAttribute("storages",storageMap);
        model.addAttribute("items",items);
        return "item-list";
    }

    @GetMapping("/item/toAdd")
    public String toAddItem(Model model){
        Map<Long, String> idNameMap = catalogService.getAllIdNameMap();
        model.addAttribute("idNameMap",idNameMap);
        return "item-add";
    }

    @PostMapping("/item/add")
    public String addItem(Item item){
        Item tmp = item;
        tmp.setCreatedTime(LocalDateTime.now()).setUpdatedTime(LocalDateTime.now());
        itemService.save(tmp);
        //还要同步库存信息
        Storage storage = new Storage().setItemId(tmp.getId())
                .setItemName(tmp.getName())
                .setInventory(item.getInventory())
                .setInventoryWarn(item.getInventory() >>> 1)
                .setCreateTime(LocalDateTime.now())
                .setUpdateTime(LocalDateTime.now());
        storageService.save(storage);
        return "redirect:/item/list";
    }


    @PostMapping("/item/update")
    public String updateItem(Item item){
        Item tmp = item;
        tmp.setUpdatedTime(LocalDateTime.now());
        itemService.updateById(tmp);
        //如果在该页面改了库存的话，还要同步库存信息
        storageService.update(new UpdateWrapper<Storage>()
                .eq("item_id",item.getId())
                .set("inventory",item.getInventory())
                .set("update_time",LocalDateTime.now()));
        return "redirect:/item/list";
    }

    @GetMapping("/item/del")
    public String delItem(@RequestParam Long itemId){
        itemService.removeById(itemId);
        storageService.removeById(itemId);
        return "redirect:/item/list";
    }

    //删多个
    @PostMapping("/item/delete/{itemIds}")
    public String delItems(@PathVariable List<Long> itemIds){
        itemService.removeByIds(itemIds);
        storageService.removeByIds(itemIds);
        return "redirect:/item/list";
    }

}

